package com.wallj.livechat;

import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Message;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;


public class MainActivity extends Activity {
    TextView tv_ip;
    EditText et_input;
    ListView lv_msg;
    Spinner spinner;
    ArrayList<String> datas;
    ManageThread manageThread;
    AdapterMessage adapterMessage;
    HashMap<String, ArrayList<EntityMessage>> messageDatas = new HashMap<>();
    String currentClientIp;
    String localIp;

    @Override

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_ip = (TextView) findViewById(R.id.tv_ip);
        et_input = (EditText) findViewById(R.id.et_input);
        lv_msg = (ListView) findViewById(R.id.lv_msg);
        spinner = (Spinner) findViewById(R.id.sp_clients);
        localIp = getIp();
        initSpinner();
        initListView();
        tv_ip.setText("本地：" + localIp);
    }

    private void initListView() {
        adapterMessage = new AdapterMessage(this, localIp);
        lv_msg.setAdapter(adapterMessage);
    }

    private void initSpinner() {
        datas = new ArrayList<>();
        datas.add("未连接");
        ArrayAdapter<String> sAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, datas);
        spinner.setAdapter(sAdapter);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                refreshCurrentClient(datas.get(i));
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {
            }
        });
    }

    private void refreshCurrentClient(String ip) {
        if (manageThread != null) {
            manageThread.setCurrentClient(ip);
            adapterMessage.getDatas().clear();
            adapterMessage.addDatas(messageDatas.get(ip));
            adapterMessage.notifyDataSetChanged();
        }
    }

    public void sendMsg(View view) {
        if (manageThread != null) {
            manageThread.sendMsg(et_input.getText() == null ? "" : et_input.getText().toString());
        }
    }

    public void openServer(View view) {
        manageThread = new ManageThread();
        manageThread.start();
    }

    class ManageThread extends Thread {
        HashMap<String, MultiClient> serverThreads;
        MultiClient currentClient;

        public ManageThread() {
            serverThreads = new HashMap<>();
        }

        public void setCurrentClient(String ip) {
            currentClientIp = ip;
            currentClient = serverThreads.get(ip);
        }

        public void sendMsg(String msg) {
            if (currentClient != null && !currentClient.isFinished()) {
                currentClient.sendMessage(msg);
            } else {
                Message toastMsg = handler.obtainMessage();
                toastMsg.what = MSG_UI_SHOW_TOAST;
                toastMsg.obj = "请先选择要通信的客户端";
                handler.sendMessage(toastMsg);
            }
        }

        @Override
        public void run() {
            super.run();
            ServerSocket server = null;
            try {
                server = new ServerSocket(5678);
                while (true) {
                    if (serverThreads.size() == 0) {
                        Message toastMsg = handler.obtainMessage();
                        toastMsg.what = MSG_UI_SHOW_TOAST;
                        toastMsg.obj = "服务已开启";
                        handler.sendMessage(toastMsg);
                    }
                    MultiClient mc = new MultiClient(server.accept());
                    mc.start();
                    serverThreads.put(mc.getClientIp(), mc);
                    setCurrentClient(mc.getClientIp());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    private void addClientIps(String ip) {
        datas.add(ip);
        messageDatas.put(ip, new ArrayList<EntityMessage>());
        ((BaseAdapter) spinner.getAdapter()).notifyDataSetChanged();
    }

    private String getIp() {
        //获取wifi服务
        WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        //判断wifi是否开启
        if (!wifiManager.isWifiEnabled()) {
            wifiManager.setWifiEnabled(true);
        }
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        int ipAddress = wifiInfo.getIpAddress();
        return intToIp(ipAddress);
    }

    private String intToIp(int i) {
        return (i & 0xFF) + "." +
                ((i >> 8) & 0xFF) + "." +
                ((i >> 16) & 0xFF) + "." +
                (i >> 24 & 0xFF);
    }

    public static final int MSG_UI_REFRESH_MSG = 0X01;
    public static final int MSG_UI_SHOW_TOAST = 0X02;
    public static final int MSG_UI_ADD_CLIENT_IP = 0x003;
    public static final int MSG_UI_MSG_SEND_SUCCESS = 0X004;
    private android.os.Handler handler = new android.os.Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MSG_UI_MSG_SEND_SUCCESS:
                    et_input.setText("");
                    break;
                case MSG_UI_ADD_CLIENT_IP:
                    String ip = (String) msg.obj;
                    addClientIps(ip);
                    break;
                case MSG_UI_REFRESH_MSG: {
                    if (adapterMessage != null) {
                        String clientip = (String) msg.obj;
                        if (currentClientIp.equals(clientip)) {
                            adapterMessage.getDatas().clear();
                            adapterMessage.addDatas(messageDatas.get(clientip));
                        }
                    }
                    break;
                }
                case MSG_UI_SHOW_TOAST: {
                    String message = (String) msg.obj;
                    if (message.contains("服务已开启")) {
                        tv_ip.setText(tv_ip.getText() + "##服务已开启");
                    }
                    Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
                    break;
                }
            }
        }
    };

    private class MultiClient extends Thread {
        private Socket client;
        PrintWriter out = null;
        boolean isFinished = false;
        String ip;

        public boolean isFinished() {
            return isFinished;
        }

        public String getClientIp() {
            if (client != null)
                return client.getInetAddress().getHostAddress();
            else
                return "";
        }

        public MultiClient(Socket c) {
            this.client = c;
            ip = getClientIp();
            Message uiMsg = handler.obtainMessage();
            uiMsg.what = MSG_UI_SHOW_TOAST;
            uiMsg.obj = client.getInetAddress() + "新建了一个连接";
            Message addMsg = handler.obtainMessage();
            addMsg.what = MSG_UI_ADD_CLIENT_IP;
            addMsg.obj = ip;
            addMsg.sendToTarget();
            uiMsg.sendToTarget();
        }

        public void sendMessage(String message) {
            EntityMessage entityMessage = new EntityMessage();
            entityMessage.setAuthor(localIp);
            entityMessage.setMessage(message);
            messageDatas.get(ip).add(entityMessage);
            Message refreshMsg = handler.obtainMessage();
            refreshMsg.what = MSG_UI_REFRESH_MSG;
            refreshMsg.obj = ip;
            refreshMsg.sendToTarget();
            out.write(message);
            out.flush();
            handler.sendEmptyMessage(MSG_UI_MSG_SEND_SUCCESS);
        }

        public void run() {
            isFinished = false;
            BufferedReader in = null;
            try {
                in = new BufferedReader(new InputStreamReader(
                        client.getInputStream()));
                out = new PrintWriter(client.getOutputStream());
                sendMessage("hello");
                while (true) {
                    String str = in.readLine();
                    if (str != null) {
                        if (str.equals("end")) {
                            break;
                        }
                        EntityMessage entityMessage = new EntityMessage();
                        entityMessage.setAuthor(ip);
                        entityMessage.setMessage(str);
                        messageDatas.get(ip).add(entityMessage);
                        Message refreshMsg = handler.obtainMessage();
                        refreshMsg.what = MSG_UI_REFRESH_MSG;
                        refreshMsg.obj = ip;
                        refreshMsg.sendToTarget();
                    }
                }
            } catch (Exception ex) {
                System.out.print(ex.getMessage());
                ex.printStackTrace();
            } finally {
                isFinished = true;
                if (ip != null)
                    messageDatas.remove(ip);
                try {
                    client.close();
                    in.close();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
